package com.gjy.statemachine.service.impl;

import com.gjy.statemachine.event.OrderStatusChangeEventEnum;
import com.gjy.statemachine.module.Order;
import com.gjy.statemachine.service.OrderService;
import com.gjy.statemachine.state.OrderStatusEnum;
import com.google.common.collect.Maps;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.statemachine.StateMachine;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Map;
import java.util.Objects;

/**
 * @author gjy
 * @version 1.0
 * @since 2025-07-02 11:35:09
 */
@Service
public class OrderServiceImpl implements OrderService {

    private static final Logger log = LoggerFactory.getLogger(OrderServiceImpl.class);

    @Resource
    private StateMachine<OrderStatusEnum, OrderStatusChangeEventEnum> orderStatusMachine;

    private long id = 1L;

    private final Map<Long, Order> orders = Maps.newConcurrentMap();

    @Override
    public Order create() {
        Order order = new Order();
        order.setOrderStatus(OrderStatusEnum.WAIT_PAYMENT);
        order.setOrderId(id++);
        orders.put(order.getOrderId(), order);
        log.info("订单创建成功: {}", order);
        return order;
    }

    @Override
    public Order pay(long id) {
        Order order = orders.get(id);
        log.info("尝试支付，订单号：{}", id);
        if (!sendEvent(MessageBuilder.withPayload(OrderStatusChangeEventEnum.PAYED)
                .setHeader("order", order).build())) {
            log.error("支付失败, 状态异常，订单号：{}", id);
        }
        return orders.get(id);
    }

    @Override
    public Order deliver(long id) {
        Order order = orders.get(id);
        log.info("尝试发货，订单号：{}", id);
        if (!sendEvent(MessageBuilder.withPayload(OrderStatusChangeEventEnum.DELIVERY)
                .setHeader("order", order).build())) {
            log.info("发货失败，状态异常，订单号：{}", id);
        }
        return orders.get(id);
    }

    @Override
    public Order receive(long id) {
        Order order = orders.get(id);
        log.info("尝试收货，订单号：{}", id);
        if (!sendEvent(MessageBuilder.withPayload(OrderStatusChangeEventEnum.RECEIVED)
                .setHeader("order", order).build())) {
            log.info("收货失败，状态异常，订单号：{}", id);
        }
        return orders.get(id);
    }


    @Override
    public Map<Long, Order> getOrders() {
        return orders;
    }

    /**
     * 发送状态转换事件
     */
    private synchronized boolean sendEvent(Message<OrderStatusChangeEventEnum> message) {
        boolean result = false;
        try {
            orderStatusMachine.start();
            result = orderStatusMachine.sendEvent(message);
        } catch (Exception e) {
            log.error("状态转换异常: {}", e.getMessage());
        } finally {
            if (Objects.nonNull(message)) {
                Order order = (Order) message.getHeaders().get("order");
                if (Objects.nonNull(order) && Objects.equals(order.getOrderStatus(), OrderStatusEnum.FINISH)) {
                    orderStatusMachine.stop();
                }
            }
        }
        return result;
    }

}
